/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package cz.muni.fi.pa165.bookingmanager.services.impl;

import cz.muni.fi.pa165.bookingmanager.dao.HotelManager;
import cz.muni.fi.pa165.bookingmanager.dao.ReservationManager;
import cz.muni.fi.pa165.bookingmanager.dao.RoomManager;
import cz.muni.fi.pa165.bookingmanager.entities.Hotel;
import cz.muni.fi.pa165.bookingmanager.entities.Reservation;
import cz.muni.fi.pa165.bookingmanager.entities.Room;
import cz.muni.fi.pa165.bookingmanager.exceptions.IllegalOrphanException;
import cz.muni.fi.pa165.bookingmanager.exceptions.NonexistentEntityException;
import cz.muni.fi.pa165.bookingmanager.interceptors.LoggingInterceptor;
import cz.muni.fi.pa165.bookingmanager.interceptors.ShiroSecuredInterceptor;
import cz.muni.fi.pa165.bookingmanager.services.HotelService;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.annotation.Resource;
import javax.ejb.EJB;
import javax.ejb.SessionContext;
import javax.ejb.Stateless;
import javax.interceptor.Interceptors;
import org.apache.shiro.authz.annotation.RequiresRoles;

/**
 *
 * @author Štefan Repček
 */
@Stateless
public class HotelServiceImpl implements HotelService {

    @EJB
    private HotelManager hotelManager;
    
    @EJB
    private RoomManager roomManager;
    
    @EJB
    private ReservationManager reservationManager;
     
    @Resource
    private SessionContext ctx;

    public void setRoomManager(RoomManager roomManager) {
        this.roomManager = roomManager;
    }

    public void setReservationManager(ReservationManager reservationManager) {
        this.reservationManager = reservationManager;
    }

    @Override
    @Interceptors({ShiroSecuredInterceptor.class, LoggingInterceptor.class})
    @RequiresRoles("admin")
    public void createHotel(Hotel hotel) throws IllegalOrphanException {
        validate(hotel);
        try {

            hotelManager.createHotel(hotel);

        } catch (Exception ex) {
            Logger.getLogger(HotelServiceImpl.class.getName()).log(Level.SEVERE, null, ex);
            ctx.setRollbackOnly();
        }
    }

    @Override
    @Interceptors({ShiroSecuredInterceptor.class, LoggingInterceptor.class})
    @RequiresRoles("admin")
    public void updateHotel(Hotel hotel) throws NonexistentEntityException, IllegalOrphanException, Exception {
        validate(hotel);
        try {

            hotelManager.updateHotel(hotel);

        } catch (Exception ex) {
            Logger.getLogger(HotelServiceImpl.class.getName()).log(Level.SEVERE, null, ex);
            ctx.setRollbackOnly();
        }
    }

    @Override
    @Interceptors({ShiroSecuredInterceptor.class, LoggingInterceptor.class})
    @RequiresRoles("admin")
    public void deleteHotel(Hotel hotel) throws NonexistentEntityException, IllegalOrphanException {
        validate(hotel);
        try {
            List<Reservation> reservations = reservationManager.findAllHotelReservations(hotel.getId());
        for (Reservation res : reservations) {
            reservationManager.deleteReservation(res);
        }
        List<Room> rooms = roomManager.findAllHotelRooms(hotel.getId());
        for (Room r : rooms) {
            roomManager.deleteRoom(r);
        }

            hotelManager.deleteHotel(hotel);

        } catch (Exception ex) {
            Logger.getLogger(HotelServiceImpl.class.getName()).log(Level.SEVERE, null, ex);
            ctx.setRollbackOnly();
        }
    }

    @Override
    @Interceptors(LoggingInterceptor.class)
    public Hotel getHotelById(Long hotelId) {
        Hotel hotel = hotelManager.getHotelById(hotelId);
        return hotel;
    }

    @Override
    @Interceptors(LoggingInterceptor.class)
    public List<Hotel> findAllHotels() {
        List<Hotel> hotels = hotelManager.findAllHotels();
        return hotels;
    }

    @Override
    @Interceptors(LoggingInterceptor.class)
    public List<Hotel> findHotelsByName(String name) {
        List<Hotel> hotels = hotelManager.findHotelsByName(name);
        return hotels;
    }

    @Override
    @Interceptors(LoggingInterceptor.class)
    public List<Hotel> findHotelsByCity(String city) {
        List<Hotel> hotels = hotelManager.findHotelsByCity(city);
        return hotels;
    }

    public static void validate(Hotel hotel) {
        if (hotel.getAdress() == null) {
            throw new IllegalArgumentException("adress is null");
        }
        if (hotel.getCity() == null) {
            throw new IllegalArgumentException("city is null");
        }
        if (hotel.getName() == null) {
            throw new IllegalArgumentException("name is null");
        }
        if (hotel.getDescription() == null) {
            throw new IllegalArgumentException("description is null");
        }

        if (hotel.getRooms() == null) {
            throw new IllegalArgumentException("rooms is null");
        }
    }

    public void setHotelManager(HotelManager hotelManager) {
        this.hotelManager = hotelManager;
    }
}
